package lru

import "reflect"

type SubLru struct {
	*Lru
}

func NewSubLru(len int) *SubLru {
	sl := &SubLru{NewLru(len)}
	return sl
}

func (sl *SubLru) ContainsKey(key interface{}) (ok bool) {
	if sl.cache == nil {
		return
	}
	sl.mu.Lock()
	defer sl.mu.Unlock()
	_, ok = sl.cache[key]
	return ok
}

func (sl *SubLru) ContainsValue(value interface{}) (ok bool) {
	if sl.cache == nil || value == nil {
		return
	}
	sl.mu.Lock()
	defer sl.mu.Unlock()
	for _, v := range sl.cache {
		if reflect.DeepEqual(value, v.Value.(*Node).Value) {
			ok = true
			break
		}
	}
	return
}

func (sl *SubLru) KeyList() (keys []interface{}) {
	if sl.cache == nil {
		return
	}
	keys = make([]interface{}, sl.l.Len())
	i := 0
	for item := sl.l.Front(); nil != item; item = item.Next() {
		keys[i] = item.Value.(*Node).Key
		i++
	}
	return
}

func (sl *SubLru) ValueList() (values []interface{}) {
	if sl.cache == nil {
		return
	}
	values = make([]interface{}, sl.l.Len())
	i := 0
	for item := sl.l.Front(); nil != item; item = item.Next() {
		values[i] = item.Value.(*Node).Value
		i++
	}
	return
}

func (sl *SubLru) AddAll(values map[interface{}]interface{}) (err error) {
	for k, v := range values {
		err = sl.Add(k, v)
		if err != nil {
			break
		}
	}
	return
}

func (sl *SubLru) Len() (len int) {
	if sl.cache == nil {
		return
	}
	len = sl.l.Len()
	return
}
